package com.ruoyi.exam.controller;

import com.ruoyi.common.annotation.Log;
import com.ruoyi.common.core.controller.BaseController;
import com.ruoyi.common.core.domain.AjaxResult;
import com.ruoyi.common.enums.BusinessType;
import com.ruoyi.common.utils.poi.ExcelUtil;
import com.ruoyi.common.utils.DateUtils;
import com.ruoyi.common.utils.SecurityUtils;
import com.ruoyi.exam.vo.ExamQuestionVo;
import com.ruoyi.exam.vo.ExamQuestionDetailVo;
import com.ruoyi.exam.vo.ExamQuestionOptionVo;
import com.ruoyi.exam.vo.ExamQuestionAnswerVo;
import com.ruoyi.exam.vo.ExamQuestionBankVo;
import com.ruoyi.exam.vo.SubmitAnswerVo;
import com.ruoyi.exam.vo.SubmitAnswerResultVo;
import com.ruoyi.exam.domain.ExamBankQuestion;
import com.ruoyi.exam.domain.ExamQuestion;
import com.ruoyi.exam.domain.ExamQuestionBank;
import com.ruoyi.exam.service.IExamBankQuestionService;
import com.ruoyi.exam.service.IExamQuestionAnswerService;
import com.ruoyi.exam.service.IExamQuestionBankService;
import com.ruoyi.exam.service.IExamQuestionOptionService;
import com.ruoyi.exam.service.IExamQuestionService;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import lombok.RequiredArgsConstructor;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.multipart.MultipartFile;
import com.ruoyi.common.core.page.TableDataInfo;
import org.apache.poi.ss.usermodel.*;
import org.apache.poi.xssf.usermodel.XSSFWorkbook;
import org.apache.poi.hssf.usermodel.HSSFWorkbook;
import java.util.ArrayList;

import javax.servlet.http.HttpServletResponse;
import java.util.Arrays;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**
 * 题目Controller
 *
 * @author Tellsea
 * @date 2025-05-30
 */
@Api(tags = "题目Controller")
@RestController
@RequestMapping("/exam/question")
@RequiredArgsConstructor(onConstructor_ = @Autowired)
public class ExamQuestionController extends BaseController {

    @Autowired
    private IExamQuestionService examQuestionService;

    @Autowired
    private IExamQuestionOptionService examQuestionOptionService;

    @Autowired
    private IExamQuestionAnswerService examQuestionAnswerService;

    @Autowired
    private IExamQuestionBankService examQuestionBankService;

    @Autowired
    private IExamBankQuestionService examBankQuestionService;

    @ApiOperation("查询题目列表")
    @PreAuthorize("@ss.hasPermi('exam:question:list')")
    @GetMapping("/list")
    public TableDataInfo<ExamQuestionVo> list(ExamQuestionVo entity) {
        return examQuestionService.queryList(entity);
    }

    @ApiOperation("查询题目所有列表")
    @GetMapping("/listAll")
    public AjaxResult listAll(ExamQuestionVo entity) {
        return AjaxResult.success("查询成功", examQuestionService.queryAll(entity));
    }

    @ApiOperation("导出题目列表")
    @PreAuthorize("@ss.hasPermi('exam:question:export')")
    @Log(title = "题目", businessType = BusinessType.EXPORT)
    @PostMapping("/export")
    public void export(HttpServletResponse response, ExamQuestionVo entity) {
        List<ExamQuestionVo> list = examQuestionService.queryAll(entity);
        ExcelUtil<ExamQuestionVo> util = new ExcelUtil<>(ExamQuestionVo.class);
        util.exportExcel(response, list, "题目数据");
    }

    @ApiOperation("下载题目导入模板")
    @PostMapping("/importTemplate")
    public void importTemplate(HttpServletResponse response) {
        ExcelUtil<ExamQuestion> util = new ExcelUtil<>(ExamQuestion.class);
        util.importTemplateExcel(response, "题目数据");
    }

    @ApiOperation("导入题目数据")
    @Log(title = "题目", businessType = BusinessType.IMPORT)
    @PostMapping("/importData")
    @Transactional
    public AjaxResult importData(MultipartFile file, boolean updateSupport) throws Exception {
        // 把所有的bankId和bankName存放到一个map中
        Map<String, Long> bankMap = new HashMap<>();
        List<ExamQuestionBankVo> bankList = examQuestionBankService.queryAll(new ExamQuestionBankVo());
        for (ExamQuestionBank bank : bankList) {
            bankMap.put(bank.getBankName(), bank.getBankId());
        }
        try {
            List<ExamQuestionVo> questionList = parseExcelFile(file);
            // 保存题目
            for (ExamQuestionVo question : questionList) {
                // 首先查询是否有相同的题目
                if (updateSupport) {
                    ExamQuestionVo queryQuestion = new ExamQuestionVo();
                    queryQuestion.setQuestionTitle(question.getQuestionTitle());
                    examQuestionService.queryList(queryQuestion);
                    if (queryQuestion.getQuestionId() != null) {
                        if (bankMap.containsKey(question.getQuestionBankName())) {
                            // 保存题库题目关联
                            ExamBankQuestion examBankQuestion = new ExamBankQuestion();
                            examBankQuestion.setBankId(bankMap.get(question.getQuestionBankName()));
                            examBankQuestion.setQuestionId(question.getQuestionId());
                            examBankQuestion.setSortOrder(1L);
                            examBankQuestionService.save(examBankQuestion);
                        }
                        continue;
                    }
                }
                question.setCreateBy(SecurityUtils.getUsername());
                question.setCreateTime(DateUtils.getNowDate());
                question.setCategoryId(1L);
                examQuestionService.save(question);
                // 设置题库ID
                // 判断是否存在
                if (bankMap.containsKey(question.getQuestionBankName())) {
                    // 保存题库题目关联
                    ExamBankQuestion examBankQuestion = new ExamBankQuestion();
                    examBankQuestion.setBankId(bankMap.get(question.getQuestionBankName()));
                    examBankQuestion.setQuestionId(question.getQuestionId());
                    examBankQuestion.setSortOrder(1L);
                    examBankQuestionService.save(examBankQuestion);
                }
                if (question.getQuestionId() != null) {
                    // 更新选项和答案
                    if (question.getOptions() != null) {
                        for (ExamQuestionOptionVo option : question.getOptions()) {
                            option.setQuestionId(question.getQuestionId());
                            option.setCreateBy(SecurityUtils.getUsername());
                            option.setCreateTime(DateUtils.getNowDate());
                            examQuestionOptionService.save(option);
                        }
                    }
                    if (question.getAnswers() != null) {
                        for (ExamQuestionAnswerVo answer : question.getAnswers()) {
                            answer.setQuestionId(question.getQuestionId());
                            answer.setCreateBy(SecurityUtils.getUsername());
                            answer.setCreateTime(DateUtils.getNowDate());
                            examQuestionAnswerService.save(answer);
                        }
                    }
                }
            }
            return AjaxResult.success("导入成功，共解析 " + questionList.size() + " 条题目数据");
        } catch (Exception e) {
            logger.error("导入题目数据失败", e);
            return AjaxResult.error("导入失败：" + e.getMessage());
        }
    }

    /**
     * 使用POI直接解析Excel文件
     * 
     * @param file Excel文件
     * @return 解析后的题目列表
     * @throws Exception
     */
    private List<ExamQuestionVo> parseExcelFile(MultipartFile file) throws Exception {
        List<ExamQuestionVo> questionList = new ArrayList<>();

        if (file.isEmpty()) {
            throw new IllegalArgumentException("上传文件不能为空");
        }

        Workbook workbook = null;
        try {
            // 根据文件扩展名创建相应的工作簿对象
            String fileName = file.getOriginalFilename();
            if (fileName.endsWith(".xlsx")) {
                workbook = new XSSFWorkbook(file.getInputStream());
            } else if (fileName.endsWith(".xls")) {
                workbook = new HSSFWorkbook(file.getInputStream());
            } else {
                throw new IllegalArgumentException("不支持的文件格式，请上传.xls或.xlsx文件");
            }

            // 获取第一个工作表
            Sheet sheet = workbook.getSheetAt(0);
            if (sheet == null) {
                throw new IllegalArgumentException("Excel文件中没有找到工作表");
            }

            // 获取数据行数（跳过表头）
            int lastRowNum = sheet.getLastRowNum();
            if (lastRowNum < 1) {
                throw new IllegalArgumentException("Excel文件中没有数据行");
            }

            // 从第二行开始读取数据（第一行为表头）
            for (int i = 1; i <= lastRowNum; i++) {
                Row row = sheet.getRow(i);
                if (row == null || isEmptyRow(row)) {
                    continue;
                }

                ExamQuestionVo question = parseRowToQuestion(row, i + 1);
                if (question != null) {
                    questionList.add(question);
                }
            }

        } finally {
            if (workbook != null) {
                workbook.close();
            }
        }

        return questionList;
    }

    /**
     * 将Excel行数据转换为ExamQuestionVo对象
     * 
     * @param row    Excel行
     * @param rowNum 行号（用于错误提示）
     * @return ExamQuestionVo对象
     */
    private ExamQuestionVo parseRowToQuestion(Row row, int rowNum) {
        try {
            ExamQuestionVo question = new ExamQuestionVo();

            // 根据新的Excel列的顺序：题型、试题内容、选项A、选项B、选项C、选项D、选项E、答案、分数、分类、难度、解析

            // 题型（第1列，索引0）
            Cell typeCell = row.getCell(0);
            if (typeCell != null) {
                String typeStr = getCellStringValue(typeCell);
                question.setQuestionType(parseQuestionTypeToString(typeStr));
            }

            // 试题内容（第2列，索引1）
            Cell contentCell = row.getCell(1);
            if (contentCell != null) {
                String content = getCellStringValue(contentCell);
                question.setQuestionContent(content);
                // 如果没有单独的题目标题，使用内容的前50个字符作为标题
                if (content.length() > 50) {
                    question.setQuestionTitle(content.substring(0, 50) + "...");
                } else {
                    question.setQuestionTitle(content);
                }
            }

            // 创建选项列表
            List<ExamQuestionOptionVo> options = new ArrayList<>();
            // 用于存储正确答案的选项标签
            String correctAnswers = "";

            // 选项A（第3列，索引2）
            Cell optionACell = row.getCell(2);
            if (optionACell != null) {
                String optionA = getCellStringValue(optionACell);
                if (!optionA.isEmpty()) {
                    ExamQuestionOptionVo optionVo = new ExamQuestionOptionVo();
                    optionVo.setOptionLabel("A");
                    optionVo.setOptionContent(optionA);
                    optionVo.setIsCorrect("0"); // 默认不是正确答案，后面会根据答案列设置
                    optionVo.setSortOrder(1L);
                    options.add(optionVo);
                }
            }

            // 选项B（第4列，索引3）
            Cell optionBCell = row.getCell(3);
            if (optionBCell != null) {
                String optionB = getCellStringValue(optionBCell);
                if (!optionB.isEmpty()) {
                    ExamQuestionOptionVo optionVo = new ExamQuestionOptionVo();
                    optionVo.setOptionLabel("B");
                    optionVo.setOptionContent(optionB);
                    optionVo.setIsCorrect("0");
                    optionVo.setSortOrder(2L);
                    options.add(optionVo);
                }
            }

            // 选项C（第5列，索引4）
            Cell optionCCell = row.getCell(4);
            if (optionCCell != null) {
                String optionC = getCellStringValue(optionCCell);
                if (!optionC.isEmpty()) {
                    ExamQuestionOptionVo optionVo = new ExamQuestionOptionVo();
                    optionVo.setOptionLabel("C");
                    optionVo.setOptionContent(optionC);
                    optionVo.setIsCorrect("0");
                    optionVo.setSortOrder(3L);
                    options.add(optionVo);
                }
            }

            // 选项D（第6列，索引5）
            Cell optionDCell = row.getCell(5);
            if (optionDCell != null) {
                String optionD = getCellStringValue(optionDCell);
                if (!optionD.isEmpty()) {
                    ExamQuestionOptionVo optionVo = new ExamQuestionOptionVo();
                    optionVo.setOptionLabel("D");
                    optionVo.setOptionContent(optionD);
                    optionVo.setIsCorrect("0");
                    optionVo.setSortOrder(4L);
                    options.add(optionVo);
                }
            }

            // 选项E（第7列，索引6）
            Cell optionECell = row.getCell(6);
            if (optionECell != null) {
                String optionE = getCellStringValue(optionECell);
                if (!optionE.isEmpty()) {
                    ExamQuestionOptionVo optionVo = new ExamQuestionOptionVo();
                    optionVo.setOptionLabel("E");
                    optionVo.setOptionContent(optionE);
                    optionVo.setIsCorrect("0");
                    optionVo.setSortOrder(5L);
                    options.add(optionVo);
                }
            }

            // 答案（第8列，索引7）
            Cell answerCell = row.getCell(7);
            if (answerCell != null) {
                correctAnswers = getCellStringValue(answerCell).toUpperCase().trim();
            }

            // 根据答案设置选项的正确性
            if (!correctAnswers.isEmpty()) {
                // 支持多选答案，如"ABC"、"A,B,C"、"A;B;C"等格式
                String[] answerArray = correctAnswers.replaceAll("[,;，；\\s]", "").split("");
                for (String answer : answerArray) {
                    if (answer.matches("[A-E]")) {
                        for (ExamQuestionOptionVo option : options) {
                            if (answer.equals(option.getOptionLabel())) {
                                option.setIsCorrect("1");
                                break;
                            }
                        }
                    }
                }
            }

            // 设置选项列表到题目对象
            question.setOptions(options);

            // 创建答案列表
            List<ExamQuestionAnswerVo> answers = new ArrayList<>();
            if (!correctAnswers.isEmpty()) {
                ExamQuestionAnswerVo answerVo = new ExamQuestionAnswerVo();
                answerVo.setAnswerContent(correctAnswers);
                answerVo.setAnswerType("1"); // 标准答案
                answers.add(answerVo);
            }
            question.setAnswers(answers);

            // 分数（第9列，索引8）
            Cell scoreCell = row.getCell(8);
            if (scoreCell != null) {
                Double scoreValue = getCellDoubleValue(scoreCell);
                if (scoreValue != null) {
                    question.setScore(java.math.BigDecimal.valueOf(scoreValue));
                }
            }

            // 分类（第10列，索引9）
            Cell categoryCell = row.getCell(9);
            if (categoryCell != null) {
                String category = getCellStringValue(categoryCell);
                // 将分类信息存储到相应字段，如果ExamQuestion有分类字段的话
                // 这里暂时存储到createBy字段作为标识，实际使用时需要根据数据库字段调整
                if (!category.isEmpty()) {
                    // question.setCategory(category); // 如果有分类字段
                    // 暂时将分类信息添加到remark字段中
                    question.setQuestionBankName(category);
                }
            }

            // 难度（第11列，索引10）
            Cell levelCell = row.getCell(10);
            if (levelCell != null) {
                String levelStr = getCellStringValue(levelCell);
                question.setDifficultyLevel(parseDifficultyLevelToString(levelStr));
            }

            // 解析（第12列，索引11）
            Cell analysisCell = row.getCell(11);
            if (analysisCell != null) {
                String analysis = getCellStringValue(analysisCell);
                if (!analysis.isEmpty()) {
                    question.setQuestionAnalysis(analysis);
                }
            }

            // 设置默认值
            question.setStatus("0"); // 正常状态
            question.setIsPublic("1"); // 公开
            question.setUseCount(0L);
            question.setCorrectCount(0L);

            return question;

        } catch (Exception e) {
            logger.error("解析第{}行数据时发生错误: {}", rowNum, e.getMessage());
            throw new RuntimeException("解析第" + rowNum + "行数据时发生错误: " + e.getMessage());
        }
    }

    /**
     * 获取单元格的字符串值
     */
    private String getCellStringValue(Cell cell) {
        if (cell == null) {
            return "";
        }

        switch (cell.getCellType()) {
            case STRING:
                return cell.getStringCellValue().trim();
            case NUMERIC:
                if (DateUtil.isCellDateFormatted(cell)) {
                    return cell.getDateCellValue().toString();
                } else {
                    // 处理数值，去掉小数点后的0
                    double numericValue = cell.getNumericCellValue();
                    if (numericValue == (long) numericValue) {
                        return String.valueOf((long) numericValue);
                    } else {
                        return String.valueOf(numericValue);
                    }
                }
            case BOOLEAN:
                return String.valueOf(cell.getBooleanCellValue());
            case FORMULA:
                return cell.getCellFormula();
            default:
                return "";
        }
    }

    /**
     * 获取单元格的双精度数值
     */
    private Double getCellDoubleValue(Cell cell) {
        if (cell == null) {
            return null;
        }

        try {
            switch (cell.getCellType()) {
                case NUMERIC:
                    return cell.getNumericCellValue();
                case STRING:
                    String strValue = cell.getStringCellValue().trim();
                    if (!strValue.isEmpty()) {
                        return Double.parseDouble(strValue);
                    }
                    return null;
                default:
                    return null;
            }
        } catch (NumberFormatException e) {
            logger.warn("无法将单元格值转换为双精度数字: {}", getCellStringValue(cell));
            return null;
        }
    }

    /**
     * 解析题目类型为字符串
     */
    private String parseQuestionTypeToString(String typeStr) {
        if (typeStr == null || typeStr.trim().isEmpty()) {
            return "1"; // 默认单选题
        }

        typeStr = typeStr.trim();
        switch (typeStr) {
            case "单选题":
            case "单选":
                return "1";
            case "多选题":
            case "多选":
                return "2";
            case "判断题":
            case "判断":
                return "3";
            case "填空题":
            case "填空":
                return "4";
            case "简答题":
            case "简答":
                return "5";
            case "综合题":
            case "综合":
                return "6";
            case "1":
            case "2":
            case "3":
            case "4":
            case "5":
            case "6":
                return typeStr;
            default:
                return "1"; // 默认单选题
        }
    }

    /**
     * 解析难度等级为字符串
     */
    private String parseDifficultyLevelToString(String levelStr) {
        if (levelStr == null || levelStr.trim().isEmpty()) {
            return "1"; // 默认简单
        }

        levelStr = levelStr.trim();
        switch (levelStr) {
            case "简单":
            case "容易":
                return "1";
            case "中等":
            case "普通":
                return "2";
            case "困难":
            case "难":
                return "3";
            case "1":
            case "2":
            case "3":
                return levelStr;
            default:
                return "1"; // 默认简单
        }
    }

    /**
     * 判断行是否为空
     */
    private boolean isEmptyRow(Row row) {
        if (row == null) {
            return true;
        }

        for (int i = row.getFirstCellNum(); i < row.getLastCellNum(); i++) {
            Cell cell = row.getCell(i);
            if (cell != null && cell.getCellType() != CellType.BLANK) {
                String cellValue = getCellStringValue(cell);
                if (!cellValue.isEmpty()) {
                    return false;
                }
            }
        }
        return true;
    }

    @ApiOperation("获取题目详细信息")
    @PreAuthorize("@ss.hasPermi('exam:question:query')")
    @GetMapping(value = "/getInfo/{questionId}")
    public AjaxResult getInfo(@PathVariable("questionId") Long questionId) {
        return AjaxResult.success("查询成功", examQuestionService.queryById(questionId));
    }

    @ApiOperation("获取题目详细信息（包含选项、答案、解析等）")
    @PreAuthorize("@ss.hasPermi('exam:question:query')")
    @GetMapping(value = "/getDetailInfo/{questionId}")
    public AjaxResult getDetailInfo(@PathVariable("questionId") Long questionId) {
        ExamQuestionDetailVo detailInfo = examQuestionService.queryDetailById(questionId, getUserId());
        if (detailInfo == null) {
            return AjaxResult.error("题目不存在");
        }
        return AjaxResult.success("查询成功", detailInfo);
    }

    @ApiOperation("获取用户当前题库的当前题目的答题记录信息")
    @PreAuthorize("@ss.hasPermi('exam:question:query')")
    @GetMapping(value = "/getBankQuestionRecord")
    public AjaxResult getBankQuestionRecord(@RequestParam("questionId") Long questionId,
            @RequestParam("bankId") Long bankId) {
        return AjaxResult.success("查询成功", examQuestionService.queryRecordInfo(questionId, bankId));
    }

    @ApiOperation("提交答案")
    @PreAuthorize("@ss.hasPermi('exam:userPracticeRecord:add')")
    @Log(title = "提交答案", businessType = BusinessType.INSERT)
    @PostMapping("/submitAnswer")
    public AjaxResult submitAnswer(@Validated @RequestBody SubmitAnswerVo submitAnswerVo) {
        try {
            Long userId = SecurityUtils.getUserId();
            SubmitAnswerResultVo result = examQuestionService.submitAnswer(submitAnswerVo, userId);
            return AjaxResult.success("提交成功", result);
        } catch (Exception e) {
            logger.error("提交答案失败", e);
            return AjaxResult.error("提交答案失败：" + e.getMessage());
        }
    }

    @ApiOperation("新增题目")
    @PreAuthorize("@ss.hasPermi('exam:question:add')")
    @Log(title = "题目", businessType = BusinessType.INSERT)
    @PostMapping("add")
    public AjaxResult add(@RequestBody ExamQuestionVo entity) {
        return toAjax(examQuestionService.save(entity));
    }

    @ApiOperation("修改题目")
    @PreAuthorize("@ss.hasPermi('exam:question:edit')")
    @Log(title = "题目", businessType = BusinessType.UPDATE)
    @PostMapping("edit")
    public AjaxResult edit(@RequestBody ExamQuestionVo entity) {
        // 更新所属题库
        examQuestionService.updateQuestionBankIds(entity);
        return toAjax(examQuestionService.updateById(entity));
    }

    @ApiOperation("删除题目")
    @PreAuthorize("@ss.hasPermi('exam:question:remove')")
    @Log(title = "题目", businessType = BusinessType.DELETE)
    @GetMapping("/remove/{questionIds}")
    public AjaxResult remove(@PathVariable Long[] questionIds) {
        return toAjax(examQuestionService.removeByIds(Arrays.asList(questionIds)) ? 1 : 0);
    }

}
